package com.ts.mediacodec

import android.content.Context
import android.media.MediaCodec
import android.media.MediaCodecInfo
import android.media.MediaFormat
import android.media.MediaMuxer
import android.opengl.EGLContext
import android.os.Handler
import android.os.HandlerThread
import android.view.Surface
import com.ts.mediacodec.EGL.EGLBase2
import com.ts.utils.FileUtils

class MediaRecorder(var path:String ,var width:Int ,var height:Int,var context:Context,var mEGLContext: EGLContext) {
    private var mMediaCodec: MediaCodec? = null
    private var mInputSurface: Surface? = null
    private var mHandler: Handler? = null
    private var mMediaMuxer: MediaMuxer? = null
    private var mEGLBase: EGLBase2?=null
    private var dataIndex = 0
    var isStart=false;
    fun getCodec(endOfStream:Boolean=false){
        if (endOfStream){
            mMediaCodec?.signalEndOfInputStream();
        }

        var bufferInfo=MediaCodec.BufferInfo();


        while (true) {


            var index = mMediaCodec?.dequeueOutputBuffer(bufferInfo, 10000)!!

            //等待超时
            if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {

                // 如果是停止 我继续循环
                // 继续循环 就表示不会接收到新的等待编码的图像
                // 相当于保证mediacodec中所有的待编码的数据都编码完成了，不断地重试 取出编码器中的编码好的数据
                // 标记不是停止 ，我们退出 ，下一轮接收到更多数据再来取输出编码后的数据

//                咱们的数据没有编码好
                if (!endOfStream) {
                    break
                }

            } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {   //媒体格式更改

                val outputFormat = mMediaCodec?.outputFormat;

                dataIndex = mMediaMuxer?.addTrack(outputFormat!!)!!;

                mMediaMuxer!!.start()

            } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {

            } else {


                var outputBuffer = mMediaCodec?.getOutputBuffer(index)

                if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                    bufferInfo.size = 0
                }

                if (bufferInfo.size != 0) {
//                    bufferInfo.presentationTimeUs=
                    val data = ByteArray(bufferInfo.size)
                    outputBuffer?.get(data)//[data]
                    FileUtils.writeContent(data)
                    outputBuffer?.position(bufferInfo.offset);

                    outputBuffer?.limit(bufferInfo.offset + bufferInfo.size)

                    mMediaMuxer?.writeSampleData(dataIndex, outputBuffer!!, bufferInfo)


                    //输出缓冲区 我们就使用完了，可以回收了，让mediacodec继续使用
                    mMediaCodec!!.releaseOutputBuffer(index, false)

                    if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                        break
                    }
                }
            }
        }

    }
    public fun stop(){
        isStart = false
        mHandler!!.post {
            getCodec(true)
            mEGLBase?.release()
            mMediaCodec!!.release()
            mMediaCodec = null
            mMediaMuxer!!.stop()
            mMediaMuxer!!.release()
            mMediaMuxer = null
            mEGLBase?.release()
            mEGLBase = null
            mInputSurface = null
        }
    }
    fun encodeFrame(textureId:Int,timestamp:Long){
        if (!isStart){
            return;
        }
        mHandler?.post {
            mEGLBase?.draw(textureId,timestamp)
            getCodec(false)

        }
    }
    fun start(){
        var mediaFormat=MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, width, height)
        // 1500kbs码率
        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE,1500_000);
        //每秒fps
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE,20)
        //关键帧间隔
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,20)

        //指定编码器颜色格式
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface)


        mMediaCodec=MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC)


        mMediaCodec?.configure(mediaFormat, null,null,MediaCodec.CONFIGURE_FLAG_ENCODE)

        mInputSurface=mMediaCodec?.createInputSurface();

        mMediaMuxer=MediaMuxer(path,MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
        val handlerThread = HandlerThread("VideoCodec")
        handlerThread.start()
        val looper = handlerThread.looper

        mHandler=Handler(looper)
        mHandler?.post {

            mEGLBase= mInputSurface?.let { EGLBase2(context,width,height, it,mEGLContext) }

            mMediaCodec?.start()

            isStart=true;
        }
    }
}